package com.bodgittandscarper.brokerhmi.view;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.logging.Logger;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingWorker;

import suncertify.db.RecordNotFoundException;

import com.bodgittandscarper.broker.types.Record;
import com.bodgittandscarper.brokerhmi.control.BASControl;
import com.bodgittandscarper.brokerhmi.model.HMIModel;
import com.bodgittandscarper.brokerhmi.model.ObservableEvent;
import com.bodgittandscarper.brokerhmi.model.PropertyListener;
import static com.bodgittandscarper.brokerhmi.model.ObservableEvent.*;

/**
 * 
 * View class holding search panel elements.
 * 
 * @author Morten Rummelhoff
 *
 */
public class SearchPanel implements PropertyListener {

	Logger log = Logger.getLogger(getClass().getName());

	private BASControl basControl;
	private HMIModel hmiModel;
	
	private RecordTableModel recordTableModel;
	
	private JPanel searchPanel;
	private JTextField locationSearchTextField;

	private JTextField nameSearchTextField;
	private JButton searchRecordButton;
	
	private JButton findAllRecordsButton;
	
	public SearchPanel(HMIModel hmiModel, BASControl basControl, RecordTableModel tableModel) {
		this.hmiModel = hmiModel;
		this.basControl = basControl;
		
		this.recordTableModel = tableModel;
		
		createGUI();
		
		this.hmiModel.addPropertyListener(this);
	}
	
	
	@Override
	public void propertyChanged(ObservableEvent event, Object value) {
		
		boolean bookRecordButtonSelected = false;
		
		if (event == LOCKRECORD_BUTTON_CHANGED ) {
			bookRecordButtonSelected = (Boolean) value;
			
			locationSearchTextField.setEnabled(!bookRecordButtonSelected );
			locationSearchTextField.setEditable(!bookRecordButtonSelected);
			
			nameSearchTextField.setEnabled(!bookRecordButtonSelected);
			nameSearchTextField.setEditable(!bookRecordButtonSelected);
		
			searchRecordButton.setEnabled(!bookRecordButtonSelected);
			findAllRecordsButton.setEnabled(!bookRecordButtonSelected);
			
		}
		else if (event == SELECTED_RECORD_ALREADY_LOCKED) {
			locationSearchTextField.setEnabled(false);
			locationSearchTextField.setEditable(false);
			
			nameSearchTextField.setEnabled(false);
			nameSearchTextField.setEditable(false);
		
			searchRecordButton.setEnabled(false);
			findAllRecordsButton.setEnabled(false);
		}
		
	}

	
	private void createGUI() {
		searchPanel = new JPanel(new BorderLayout());
		searchPanel.setBorder(BorderFactory.createTitledBorder("Record Search"));


		JPanel horizontalPanel = new JPanel();
		horizontalPanel.setLayout(new GridBagLayout());

		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.WEST;
		gbc.ipady = 2;	
		gbc.insets = new Insets(2, 2, 2, 2);

		gbc.gridy++;

		gbc.gridx = 0;
		JLabel label = new JLabel("NAME");
		horizontalPanel.add(label, gbc);
		gbc.gridx = 1;
		nameSearchTextField = new JTextField();
		nameSearchTextField.setColumns(18);
		horizontalPanel.add(nameSearchTextField, gbc);

		gbc.gridx = 0;
		gbc.gridy++;
		horizontalPanel.add(new JLabel("and/or"), gbc);

		gbc.gridy++;
		horizontalPanel.add(new JLabel("LOCATION"), gbc);
		gbc.gridx = 1;
		locationSearchTextField = new JTextField();
		locationSearchTextField.setColumns(18);
		horizontalPanel.add(locationSearchTextField, gbc);


		//buttonpanel
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		findAllRecordsButton = new JButton("All Records");
		findAllRecordsButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		buttonPanel.add(findAllRecordsButton);
		searchRecordButton = new JButton("Search");
		searchRecordButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		buttonPanel.add(searchRecordButton);
		
		searchPanel.add(horizontalPanel);
		searchPanel.add(buttonPanel, BorderLayout.PAGE_END);


		findAllRecordsButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				//Use the SwingWorker to avoid blocking the EDT when calling remote objects.
				new SwingWorker<String, Object>() {

					private Record[] records = null;
					private String result = null;
					
					@Override
					protected String doInBackground() {
						
						try {
							records = basControl.getAllRecords();
							result = "Found " + records.length + " record(s).";
						} catch (RemoteException e) {
							result = "Unable to search in records. Cause: " + e.getMessage();
						} 
						
						
						return result; 	
					}
					
					@Override
					protected void done() {
						
						hmiModel.notifyPropertyChange(ObservableEvent.STATUS_TEXT_CHANGED, result);
									
						recordTableModel.updateModel(records);
						recordTableModel.fireTableDataChanged();
						
					}
					

				}.execute();
				
			}
		});
		
		searchRecordButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				
				//Use the SwingWorker to avoid blocking the EDT when calling remote objects.
				new SwingWorker<String, Object>() {

					private Record[] records = null;
					private String result = null;
					
					@Override
					protected String doInBackground() {
						
						try {
							records = basControl.
								findExactRecords(nameSearchTextField.getText(), 
									locationSearchTextField.getText());
							result = "Found " + records.length + " record(s) that matches search criteria.";
						} catch (RemoteException e) {
							result = "Unable to search in records. Cause: " + e.getMessage();
						} catch (RecordNotFoundException e) {
							result = "No records matches search criteria.";
						} 
						
						
						return result; 	
					}
					
					@Override
					protected void done() {
						
						hmiModel.notifyPropertyChange(ObservableEvent.STATUS_TEXT_CHANGED, result);
									
						recordTableModel.updateModel(records);
						recordTableModel.fireTableDataChanged();
						
					}
					

				}.execute();

			}
		});


	}
	
	/**
	 * Gets the presentation of the search panel.
	 * 
	 * @return Component presentation of the search panel.
	 */
	public JComponent getPresentation() {
		return searchPanel;
	}
}
